using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using MultiVMR9cs;

namespace Sample
{
    public partial class VideoControlPanel : UserControl
    {
        private string _caption = "Caption";
        private VideoSource _source;

        #region ctor

        public VideoControlPanel(VideoSource source,string caption)
        {
            _source = source;

            // hook the Graph Events so we can start/stop the TimeSlider timer
            _source.GraphPaused += new EventHandler(_source_GraphStopped);
            _source.GraphStopped += new EventHandler(_source_GraphStopped);
            _source.GraphRun += new EventHandler(_source_GraphRun);

            _caption = caption;
            InitializeComponent();
            Dock = DockStyle.Top;

            // set the extents of the Timeslider
            _timeSliderControl.Extent = (int)(_source.Duration / 10000);
            _timeSliderControl.Min = 0;
            _timeSliderControl.Max = _timeSliderControl.Extent;

            // let the closeButton know who's boss
            closeButton.Tag = this;

            // run the Video Source
            _source.Run();

            // deactivate controls that aren't pertinent to the Source Type
            if (source.GetType() != typeof(VideoSource))
            {
                _loopCheckBox.Visible = false;
                _keepAspectRatio.Visible = false;
                _volumeTrackBar.Visible = false;
            }
        }

        #endregion

        // event that is raised when the Clone Source is clicked
        public event EventHandler CloneSource;

        public VideoSource VideoSource
        {
            get
            {
                return _source;
            }
        }

        public string Caption
        {
            get
            {
                return _caption;
            }
        }

        #region Event Handlers

        private void _captionPanel_Paint(object sender, PaintEventArgs e)
        {
            // draw the caption
            e.Graphics.DrawString(_caption, Font, Brushes.White, new PointF(0, 0));
        }

        private void _playButton_Click(object sender, EventArgs e)
        {
            _source.Run();
        }

        private void _pauseButton_Click(object sender, EventArgs e)
        {
            _source.Pause();
        }

        private void _stopButton_Click(object sender, EventArgs e)
        {
            _source.Stop();
        }

        void _source_GraphRun(object sender, EventArgs e)
        {
            // start up the TimeSlider Timer
            _timeSliderTimer.Enabled = true;
        }

        void _source_GraphStopped(object sender, EventArgs e)
        {
            // stop the TimeSlider Timer
            _timeSliderTimer.Enabled = false;
        }

        private void _timeSliderTimer_Tick(object sender, EventArgs e)
        {
            // update the positions of the time slider
            _timeSliderControl.Pos = (int)(_source.CurrentPosition / 10000);
        }

        private void _resetButton_Click(object sender, EventArgs e)
        {
            // reset the transform values to defaults
            _alphaTrackBar.Value = 1000;

            _xscaleTrackBar.Value = _xposTrackBar.Value = 500;
            _yscaleTrackBar.Value = _yposTrackBar.Value = 500;
            _zscaleTrackBar.Value = _zposTrackBar.Value = 500;

            _xrotTrackBar.Value = 0;
            _yrotTrackBar.Value = 0;
            _zrotTrackBar.Value = 0;
        }

        private void _volumeTrackBar_ValueChanged(object sender, EventArgs e)
        {
            if (_volumeTrackBar.Tracking)
            {
                _source.Volume = (float)_volumeTrackBar.Value / 1000f;
            }
        }

        private void _visibleCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            _source.Visible = _visibleCheckBox.Checked;
        }

        private void _loopCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            _source.Loop = _loopCheckBox.Checked;
        }

        private void _keepAspectRatio_CheckedChanged(object sender, EventArgs e)
        {
            _source.KeepAspectRatio = _keepAspectRatio.Checked;
        }

        private void _zenableCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            _source.ZBufferEnabled = _zenableCheckBox.Checked;
        }

        #endregion

        #region Caption Drag/Drop Methods

        private Rectangle dragBoxFromMouseDown;

        private void _captionPanel_MouseDown(object sender, MouseEventArgs e)
        {
            // Remember the point where the mouse down occurred. The DragSize indicates
            // the size that the mouse can move before a drag event should be started.                
            Size dragSize = SystemInformation.DragSize;

            // Create a rectangle using the DragSize, with the mouse position being
            // at the center of the rectangle.
            dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2),
                                                           e.Y - (dragSize.Height / 2)), dragSize);
        }

        private void _captionPanel_MouseMove(object sender, MouseEventArgs e)
        {
            // If the mouse moves outside the rectangle, start the drag.
            if (dragBoxFromMouseDown != Rectangle.Empty &&
                !dragBoxFromMouseDown.Contains(e.X, e.Y))
            {
                DoDragDrop(this, DragDropEffects.Move);
            }
        }

        private void _captionPanel_MouseUp(object sender, MouseEventArgs e)
        {
            // Reset the drag rectangle when the mouse button is raised.
            dragBoxFromMouseDown = Rectangle.Empty;
        }

        private void VideoControlPanel_DragEnter(object sender, DragEventArgs e)
        {
            //see if it is a TypeOf DSFilterTreeViewNode
            if (e.Data.GetDataPresent(typeof(VideoControlPanel)))
            {
                object o = e.Data.GetData(typeof(VideoControlPanel));
                if (o != this)
                {
                    e.Effect = DragDropEffects.Move;
                }
                else
                {
                    e.Effect = DragDropEffects.None;
                }
            }
            dragBoxFromMouseDown = Rectangle.Empty;
        }

        private void VideoControlPanel_DragDrop(object sender, DragEventArgs e)
        {
            VideoControlPanel vc = (VideoControlPanel)e.Data.GetData(typeof(VideoControlPanel));
            if (vc != null)
            {
                vc._source.ZOrder = this._source.ZOrder;
                this.Parent.Controls.SetChildIndex(vc, this.Parent.Controls.IndexOf(this));
            }
        }

        #endregion

        #region Control Handlers

        private void _timeSliderControl_ValuesChanged(object sender, EventArgs e)
        {
            switch (_timeSliderControl.TrackMode)
            {
                case TimeSliderTrackMode.None:
                    break;
                case TimeSliderTrackMode.StartTime:
                    _source.StartPosition = (long)_timeSliderControl.Min * 10000;
                    break;
                case TimeSliderTrackMode.StopTime:
                    _source.EndPosition = (long)_timeSliderControl.Max * 10000;
                    break;
                case TimeSliderTrackMode.CurrentTime:
                    _source.CurrentPosition = (long)_timeSliderControl.Pos * 10000;
                    break;
                default:
                    break;
            }
        }

        private void _alphaTrackBar_ValueChanged(object sender, EventArgs e)
        {
            _source.Alpha = (float)_alphaTrackBar.Value / 1000f;
        }

        private void _posTrackBar_ValueChanged(object sender, EventArgs e)
        {
            ColorTrackBar tb = sender as ColorTrackBar;
            if (tb == _xposTrackBar)
            {
                _source.XPosition = ((float)(tb.Value - 500) / 500f) * 2f;
            }
            else if (tb == _yposTrackBar)
            {
                _source.YPosition = ((float)(tb.Value - 500) / 500f) * 2f;
            }
            else
            {
                _source.ZPosition = ((float)(tb.Value - 500) / 500f) * 2f;
            }
        }

        private void _scaleTrackBar_ValueChanged(object sender, EventArgs e)
        {
            ColorTrackBar tb = sender as ColorTrackBar;
            if (tb == _xscaleTrackBar)
            {
                _source.XScale = (float)tb.Value / 500;
            }
            else if (tb == _yscaleTrackBar)
            {
                _source.YScale = (float)tb.Value / 500;
            }
            else
            {
                _source.ZScale = (float)tb.Value / 500;
            }
        }

        private void _rotTrackBar_ValueChanged(object sender, EventArgs e)
        {
            ColorTrackBar tb = sender as ColorTrackBar;
            if (tb == _xrotTrackBar)
            {
                _source.XRotation = (float)tb.Value / 1000f;
            }
            else if (tb == _yrotTrackBar)
            {
                _source.YRotation = (float)tb.Value / 1000f;
            }
            else
            {
                _source.ZRotation = (float)tb.Value / 1000f;
            }
        }

        private void _borderAlphaSlider_ValueChanged(object sender, EventArgs e)
        {
            _source.BorderColor = Color.FromArgb((int)(255f * ((float)_borderAlphaSlider.Value / 1000f)), _borderColorButton.BackColor);
        }

        private void _borderColorButton_Click(object sender, EventArgs e)
        {
            ColorDialog cd = new ColorDialog();
            cd.Color = _borderColorButton.BackColor;

            if (cd.ShowDialog() == DialogResult.OK)
            {
                _borderColorButton.BackColor = cd.Color;
                _source.BorderColor = Color.FromArgb((int)(255f * ((float)_borderAlphaSlider.Value / 1000f)), _borderColorButton.BackColor);
            }

            cd.Dispose();
        }

        #endregion

        private void _cloneSourceButton_Click(object sender, EventArgs e)
        {
            // raise the CloneSource event
            if (CloneSource != null)
            {
                CloneSource(this, new EventArgs());
            }
        }
    }
}
